/**
 * 
 */
package it.polimi.cg16.client;

import it.polimi.cg16.client.gui.GameBoardGUI;
import it.polimi.cg16.model.Terrain;

import java.io.IOException;

import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;

/**
 * @author Andrea & Michele
 * 
 */
public class GUIClientController extends ClientController {

    private GameBoardGUI gameBoardGui;
    private MyActionListener actionListener;
    private boolean firstUpdate;

    public GUIClientController(NetAdapter netAdapter) {
        super(netAdapter);

        actionListener = new MyActionListener(netAdapter);
        gameBoardGui = new GameBoardGUI(gameBoard, actionListener, player);
        firstUpdate = true;
    }

    public void run() {

        helloMessage();

        do {
            receiveObject();
        } while (!"bye".equals(message));
        close();
    }

    /**
     * Show messaage dialog with close information and perform closing
     * operations
     */
    @Override
    public void close() {
        JFrame messageFrame = new JFrame();
        messageFrame.setVisible(true);
        messageFrame.setLocationRelativeTo(null);
        JOptionPane.showMessageDialog(messageFrame, "Closing client...", "Sheepland!", JOptionPane.ERROR_MESSAGE);
        super.close();
    }

    /**
     * Send an hello message
     * 
     * @throws IOException
     */
    public void helloMessage() {
        System.out.println("Waiting for other players...");
    }

    /**
     * Performs end turn action. Reset all buttons
     */
    @Override
    public void endTurn() {
        gameBoardGui.resetAll();
        gameBoardGui.setInfoLabel("Wait! Other player turn...");
    }

    /**
     * Show the result to the player
     */
    @Override
    public void showResultsClient() {
        super.showResultsClient();
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                gameBoardGui.showResults(otherPlayers, sheepsPerTerrain);
            }
        });
    }

    /**
     * Enables player's shepherd button that can be chosen
     */
    @Override
    public void chooseShepherd() {
        gameBoardGui.resetAll();
        gameBoardGui.setInfoLabel("Choose a shepherd...");
        gameBoardGui.enableMyShepherd();
    }

    /**
     * Method to enable free cell in the gameboard
     */
    @Override
    public void chooseCellClient() {
        gameBoardGui.resetAll();
        gameBoardGui.setInfoLabel("Choose a cell...");
        gameBoardGui.enableCells();
    }

    /**
     * Method to receive and enable buyable terrain card in the gameboard
     */
    @Override
    public void chooseCardClient() {
        gameBoardGui.resetAll();
        gameBoardGui.setInfoLabel("Choose a terrain card to buy...");
        int length = netAdapter.readInt();
        int[] terrainConstant = new int[length];
        int[] cost = new int[length];
        for (int i = 0; i < length; i++) {
            terrainConstant[i] = netAdapter.readInt();
            cost[i] = netAdapter.readInt();
            for (Terrain t : Terrain.values()) {
                if (t.getTypeConstant() == terrainConstant[i]) {
                    gameBoardGui.enableCards(t);
                }
            }
        }
    }

    /**
     * Method to enable selectable sheep in a region near shepherd
     */
    @Override
    public void chooseSheepClient() {
        gameBoardGui.resetAll();
        gameBoardGui.setInfoLabel("Choose a sheep from a region...");
        int chosenShepherd = netAdapter.readInt();
        gameBoardGui.enableSheep(player.getShepherds().get(chosenShepherd).getCell().getRegion1());
        gameBoardGui.enableSheep(player.getShepherds().get(chosenShepherd).getCell().getRegion2());
    }

    /**
     * Method to enable available moves in the gameboard
     */
    @Override
    public void chooseMoveClient() {
        gameBoardGui.resetAll();
        gameBoardGui.setInfoLabel("Choose a move to do...");
        int length = netAdapter.readInt();
        for (int i = 0; i < length; i++) {
            int moveType = netAdapter.readInt();
            for (MoveClient m : MoveClient.values()) {
                if (m.getType() == moveType) {
                    gameBoardGui.enableMoves(m);
                }
            }
        }

    }

    /**
     * Method to update client data initially
     */
    @Override
    public void initialUpdateClient() {
        super.initialUpdateClient();
        if (firstUpdate) {
            gameBoardGui.drawFrame();
            firstUpdate = false;
        } else {
            gameBoardGui.updateFrame();

        }
    }

    /**
     * Method to update client data
     */
    @Override
    public void updateClient() {
        super.updateClient();
        if (!isUpdate) {
            gameBoardGui.initShepherds();
            isUpdate = true;
        }
        gameBoardGui.updateFrame();
    }

    /**
     * Method to update client money
     */
    @Override
    public void updateMoneyClient() {
        if ("#updateMoney#".equals(netAdapter.readString())) {
            int money = netAdapter.readInt();
            player.setMoney(money);
            if (!firstUpdate) {
                gameBoardGui.setMoneyLabel(money);
            }
        }
    }
}